using UnityEngine;
using System.Collections;
using System.Collections.Generic;
using System;

public class UnityGUIDemo : MonoBehaviour
{
	Texture2D greenLine;
    Texture2D redLine;
    FakeLines theLines;

    int[] rawData;
    int[] dungeonData;

    bool displayDungeon = false;
    bool displayRaw = true;

    public int width = 200;
    public int height = 200;
	
	public int resetwidth = 0;
	public int resetheight = 0;

    public List<Texture2D> displayTexture = new List<Texture2D>();

    public Texture2D impass;
    public Texture2D passable;

    public int chunkSize = 1;

    public int xOffset = 100;
    public int yOffset = 50;

    public Color impassColor;
    public Color passableColor;

    public int[] conversionRate = new int[10];
	
    string dunWidth;
    string dunHeight;
    string dropCountString;
    string dropSizeString;
    public int dropCount = 60;
    public int dropSize = 4;

    System.Random rnd = new System.Random();
	

    enum BlockDirection
    {
        NONE
        ,LEFT
        ,RIGHT
        ,UP
        ,DOWN
    }
    

	void Start () {
		
        dunWidth = width.ToString();
        dunHeight = height.ToString();
        dropCountString = dropCount.ToString();
        dropSizeString = dropSize.ToString();

        ResetData();

        if (impass == null)
        {
            impass = new Texture2D(chunkSize, chunkSize);
            Color[] impassColorDump = new Color[chunkSize * chunkSize];
            for (int cIndex = 0; cIndex < impassColorDump.Length; cIndex++) impassColorDump[cIndex] = impassColor;
            impass.SetPixels(impassColorDump);
            impass.Apply();
        }

        if (passable == null)
        {
            passable = new Texture2D(chunkSize, chunkSize);
            Color[] passableColorDump = new Color[chunkSize * chunkSize];
            for (int cIndex = 0; cIndex < passableColorDump.Length; cIndex++) passableColorDump[cIndex] = passableColor;
            passable.SetPixels(passableColorDump);
            passable.Apply();
        }

        if (displayTexture.Count == 0)
        {
            Color color = new Color(0, 0, 0, 1);
            Texture2D temp;

            for (int i = 0; i < 10; i++)
            {
                temp = new Texture2D(chunkSize, chunkSize);
                Color[] colorDump = new Color[chunkSize * chunkSize];
                for (int cIndex = 0; cIndex < colorDump.Length; cIndex++) colorDump[cIndex] = color;


                temp.SetPixels(colorDump);
                temp.Apply();

                displayTexture.Add(temp);
                color.r += 0.11f;
                color.g -= 0.11f;
            }
        }
		
		greenLine = new Texture2D(1, 1, TextureFormat.ARGB32, false);
        greenLine.SetPixel(0, 0, Color.green);
        greenLine.Apply();

        redLine = new Texture2D(1, 1, TextureFormat.ARGB32, false);
        redLine.SetPixel(0, 0, Color.red);
        redLine.Apply();
              
		theLines = new FakeLines();

        
	}

    private void ResetData()
    {
        rawData = new int[width * height];
        dungeonData = new int[width * height];
        for (int i = 0; i < rawData.Length; i++)
        {
            rawData[i] = 0;
            dungeonData[i] = 0;
        }
    }

    void Update()
    {
		
	}

    public void OnGUI()
    {

        GUILayout.BeginVertical();

        GUILayout.BeginHorizontal();

        if (GUILayout.Button("Set Dungeon Size"))
        {
		  ProcessWidthAndHeight();
        }

        if (GUILayout.Button("Split Once"))
        {
           theLines.Split();
        }

        if (GUILayout.Button("Split All"))
        {
           DoConvert();
        }


        GUILayout.EndHorizontal();

        GUILayout.Label("Width");
        dunWidth = GUILayout.TextField(dunWidth, GUILayout.Width(90));
        GUILayout.Label("Height");
        dunHeight = GUILayout.TextField(dunHeight, GUILayout.Width(90));
        GUILayout.Label("No. of Splits");
        dropCountString = GUILayout.TextField(dropCountString, GUILayout.Width(90));
		
				
		ProcessCountAndSize();
				
        GUILayout.EndVertical();

        if (Event.current.type == EventType.repaint)
        {
            if(displayRaw) DisplayRawData();
            if (displayDungeon) DisplayDungeonData();
			
            for (int i = 0; i < theLines.oldLines.Count; i++)
            {
                Graphics.DrawTexture(theLines.oldLines[i], redLine);
            }

            for (int i = 0; i < theLines.newLines.Count; i++)
            {
                Graphics.DrawTexture(theLines.newLines[i], greenLine);
            }
        }

    }

    private void DoDrop()
    {
        System.Diagnostics.Stopwatch watch = new System.Diagnostics.Stopwatch();
        watch.Start();
        ResetData();
        for (int i = 0; i < dropCount; i++)
        {
            Drop(rnd.Next(0, width), rnd.Next(0, height), dropSize, BlockDirection.NONE);
        }
        watch.Stop();
        print("Time Taken: " + watch.Elapsed);
    }

    private void PlaceBorder()
    {
        
        for (int i = 0; i < width; i++) rawData[i] = 0;
        for (int i = width * (height - 1); i < width * height; i++) rawData[i] = 0;
        int index = 0;
        for (int i = 0; i < height; i++)
        {
            index = i * width;
            rawData[index] = 0;
        }
        for (int i = 0; i < height; i++)
        {
            index = i * width + (width - 1);
            rawData[index] = 0;
        }
    }
	
    private void DoConvert()
    {
        displayRaw = false;
    }
	
    private void ProcessCountAndSize()
    {
        try
        {
            dropCount = int.Parse(dropCountString);
            dropSize = int.Parse(dropSizeString);
        }
        catch
        {
            dropCountString = dropCount.ToString();
            dropSizeString = dropSize.ToString();
        }
    }

    private void ProcessWidthAndHeight()
    {
        try
        {
            int newWidth = int.Parse(dunWidth);
            int newHeight = int.Parse(dunHeight);

            if (newWidth != width || newHeight != height)
            {
                width = newWidth;
                height = newHeight;
                ResetData();
            }
        }
        catch 
        {
            dunWidth = width.ToString();
            dunHeight = height.ToString();
        }
		        
    }


    private void DisplayDungeonData()
    {

        Rect pos = new Rect();
        pos.width = chunkSize;
        pos.height = chunkSize;
        for (int i = 0; i < dungeonData.Length; i++)
        {
            pos.x = xOffset + (i % width) * chunkSize;
            pos.y = yOffset + (i / width) * chunkSize;
            if(dungeonData[i] == 0) Graphics.DrawTexture(pos, impass);
            else Graphics.DrawTexture(pos, passable);
        }

    }

    private void DisplayRawData()
    {
        Rect pos = new Rect();
        pos.width = chunkSize;
        pos.height = chunkSize;
        for (int i = 0; i < rawData.Length; i++)
        {
            pos.x = xOffset + (i % width) * chunkSize;
            pos.y = yOffset + (i / width) * chunkSize;
          
            Graphics.DrawTexture(pos, displayTexture[rawData[i]]);
        }
    }
	
    void Drop(int x, int y, int level, BlockDirection bd)
    {
        displayDungeon = false;
        displayRaw = true;

        if (x < 0 || x >= width || y < 0 || y >= height) return;
        
        int index = x + y * width;
        rawData[index] += level;
        if (rawData[index] > 9) rawData[index] = 9;
        if (level > 1)
        {
            level -= 1;
            if(bd != BlockDirection.LEFT) Drop(x - 1, y, level, BlockDirection.RIGHT);
            if(bd != BlockDirection.RIGHT) Drop(x + 1, y, level, BlockDirection.LEFT);
            if(bd != BlockDirection.UP) Drop(x, y - 1, level, BlockDirection.DOWN);
            if(bd != BlockDirection.DOWN) Drop(x, y + 1, level, BlockDirection.UP);
        }
    }
}
